package com.jianying.shared;

import java.math.RoundingMode;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
@Component("utils")
public class Utils {
	
	@Autowired
	private MessageSource messageSource;
	
	private static final String ALL_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	
	private static final String ALL_NUMBERS = "0123456789";
	
	private static final String DATE_FORMATE = "yyyy-MM-dd";
	
	private static final String DATE_STRTIME = "yyyyMMddHHmmss";
	
	private static final String DATE_SHORTSTRTIME = "yyMMddHH";
	
	public static String token() {
		return uuid() + new Date().getTime();
	}
	
	public static String uuid() {
		return UUID.randomUUID() + "-" + randomString(16);
	}
	
	public static <E> E jsonToBean(String json, Class<E> cls) {
		try {
			if(json == null || json.trim().equals("")){
				return null;
			}
			ObjectMapper mapper = new ObjectMapper();
			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
			E vo = mapper.readValue(json, cls);
			return vo;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	public static <E> E jsonToBean(String json, TypeReference<E> trf) {
		try {
			if(json == null || json.trim().equals("")){
				return null;
			}
			ObjectMapper mapper = new ObjectMapper();
			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
			E vo = mapper.readValue(json, trf);
			return vo;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	@SuppressWarnings({ "unchecked", "deprecation" })
	public static Map<String, Object> jsonToMap(String json) {
		try {
			if(json == null || json.trim().equals("")){
				return null;
			}
			ObjectMapper mapper = new ObjectMapper();
			mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
			Map<String, Object> map = mapper.readValue(json, Map.class);
			return map;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	public static String objectToJson(Object obj){
		try {
			ObjectMapper mapper = new ObjectMapper();
			return mapper.writeValueAsString(obj);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public static String randomString(int length) {
		StringBuffer sb = new StringBuffer();
		Random random = new Random();
		for (int i = 0; i < length; i++) {
			sb.append(ALL_CHARS.charAt(random.nextInt(ALL_CHARS.length())));
		}
		return sb.toString();
	}
	
	public static String randomNumber(int length){
		StringBuffer sb = new StringBuffer();
		Random random = new Random();
		for (int i = 0; i < length; i++) {
			sb.append(ALL_NUMBERS.charAt(random.nextInt(ALL_NUMBERS.length())));
		}
		return sb.toString();
	}
	
	public static boolean stringBlank(String str){
		return str == null || str.trim().equals("");
	}
	
	public static String underscore(String name) {
		StringBuilder result = new StringBuilder();
		if ((name != null) && (name.length() > 0)) {
			result.append(name.substring(0, 1).toLowerCase());
			for (int i = 1; i < name.length(); ++i) {
				String s = name.substring(i, i + 1);
				if (s.equals(s.toUpperCase())) {
					result.append("_");
					result.append(s.toLowerCase());
				} else {
					result.append(s);
				}
			}
		}
		return result.toString();
	}
	
	public static Boolean jsonValid(String json) {
		try {
			JSON.parse(json);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	
	//------------------------------------------------------------------------------------

	public static Date stringToDate(String value){
		if(stringBlank(value)){
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMATE);
		try {
			return sdf.parse(value);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static Date stringFormateToDate(String value){
		if(stringBlank(value)){
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMATE);
		try {
			return sdf.parse(value);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static String dateTimeToString(Date date){
		java.text.DateFormat format = new java.text.SimpleDateFormat(DATE_STRTIME);
		return format.format(date);
	}
	
	public static String dateTimeToShortString(Date date){
		java.text.DateFormat format = new java.text.SimpleDateFormat(DATE_SHORTSTRTIME);
		return format.format(date);
	}
	
	public static String dateToString(Date date){
		if(date == null){
			return null;
		}
		java.text.DateFormat format = new java.text.SimpleDateFormat(DATE_FORMATE);
		return format.format(date);
	}
	
	public static Date addDays(Date date, int n){
		if(date == null){
			return null;
		}
	    Calendar c = Calendar.getInstance();
	    c.setTime(date);
	    c.add(Calendar.DATE, n);
	    return c.getTime();
	}
	
	public static Date addYears(Date date, int n){
		if(date == null){
			return null;
		}
	    Calendar c = Calendar.getInstance();
	    c.setTime(date);
	    c.add(Calendar.YEAR, n);
	    return c.getTime();
	}
	
	public static Date nextNDateBeginning(int n){
		Calendar calendar=Calendar.getInstance();   
		calendar.setTime(new Date()); 
		calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)+n);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
	public static Date nextNDateEnd(int n){
		Calendar calendar=Calendar.getInstance();   
		calendar.setTime(new Date()); 
		calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)+n);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTime();
	}
	
	//------------------------------------------------------------------------------------
	
	public String getLocalLanguage(String key) {
		try {
			Locale locale = LocaleContextHolder.getLocale();
			String value = messageSource.getMessage(key, null, locale);
			return value;
		} catch (Exception e) {
			return "don't have this(" + key + ") key";
		}
		
	}
	
	public static String md5Up32(String msg) {
        try {
            MessageDigest digest = MessageDigest.getInstance("md5");
            byte[] result = digest.digest(msg.getBytes());
            StringBuffer buffer = new StringBuffer();
            for (byte b : result) {
                int number = b & 0xff;
                String str = Integer.toHexString(number);
                if (str.length() == 1) {
                    buffer.append("0");
                }
                buffer.append(str);
            }
            return buffer.toString().toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }
    }
	
	public static Double doubleFormat2(double value) {  
        DecimalFormat df = new DecimalFormat("0.00");  
        df.setRoundingMode(RoundingMode.HALF_UP);  
        return Double.valueOf(df.format(value));  
    }
	
	public static String firstImage(String images) {
		List<String> ia = imageArray(images);
		return ia.isEmpty() ? null : ia.get(0);
	}
	
	public static List<String> imageArray(String images) {
		List<String> is = new ArrayList<String>();
		for(String i : split(images, ";")) {
			if(!i.trim().equals("")) {
				is.add(i.trim());
			}
		}
		return is;
	}
	
	public static List<String> split(String images, String splitor) {
		if(images == null || images.trim().equals("")) {
			return new ArrayList<>();
		}
		return Arrays.asList(images.split(splitor));
	}
	
	public static String nullString(Object obj) {
		return obj == null ? "" : obj.toString();
	}
}
